package it.okkam.longwell.ui.command;

import it.okkam.webid.model.DataModel;

import java.util.HashMap;
import javax.servlet.ServletException;

import org.apache.velocity.VelocityContext;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.tdb.TDBFactory;
import com.hp.hpl.jena.vocabulary.RDF;

import edu.mit.simile.longwell.LongwellServer;
import edu.mit.simile.longwell.ui.FlairMessage;
import edu.mit.simile.longwell.ui.InjectionManager;
import edu.mit.simile.longwell.ui.command.CommandBase;

public class SaveUserBasicCommand extends CommandBase {

	HashMap<String, String> userForSession = new HashMap<String, String>();
	public static boolean userInput = false;

	private Model inputModel = null;
	final protected String m_template;
	VelocityContext vcContext = null;

	public SaveUserBasicCommand(InjectionManager injectionManager,
			String template) {
		super(injectionManager);
		m_template = template;
	}

	@Override
	/**
	 * Save the user login info to ttl/rdf store
	 * this is for basic user registration, without webid information
	 */
	public void execute(FlairMessage msg) throws ServletException {
		String mail = msg.m_request.getParameter("email");
		String username = msg.m_request.getParameter("username");
		
		
		// load the dataset into the memory
		inputModel = LongwellServer.getModelForAuthentication();	

		// if the user is not already registered
		if (!(checkDuplicate("foaf:nickname", username)
				|| checkDuplicate("foaf:mbox", mail))) 
		{
			registerUsers(msg);
		}
		// user already registered
		else {
			try {

				vcContext = createContext(msg);
				vcContext.put("application", "BCC - Save_user");
				// vcContext.put("error", error);
				userForSession.put(msg.m_request.getSession().getId(),
						"user_duplicate");
				vcContext.put("sessionId", msg.m_request.getSession().getId());
				vcContext.put("hashError", userForSession);
				msg.m_ve.mergeTemplate(m_template, vcContext,
						msg.m_response.getWriter());
				userInput = true;

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	
	private boolean checkDuplicate( String property, String value){
		
		boolean duplicate = false;
		String prefix = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
			+ "PREFIX : <http://www.semanticweb.org/ontologies/2011/9/Rivela-Flussi.owl#> "
			+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ";
		String queryString ;
			queryString= prefix + '\n'
			+ "ask { ?user " + property + "  \"" + value +"\" . } ";

		Query query = QueryFactory.create(queryString);
		QueryExecution qexec = QueryExecutionFactory.create(query, inputModel);

		duplicate = qexec.execAsk();
		
		return duplicate;
		
	}
	
	private void registerUsers (FlairMessage msg){
		String riv = "http://www.semanticweb.org/ontologies/2011/9/Rivela-Flussi.owl#";
		String foaf = "http://xmlns.com/foaf/0.1/";
		String xfoaf = "http://www.foafrealm.corrib.org/xfoaf/0.1/";
		String name = msg.m_request.getParameter("name");
		String lastname = msg.m_request.getParameter("cognome");
		String mail = msg.m_request.getParameter("email");
		String username = msg.m_request.getParameter("username");
		
		DataModel dataModel = new DataModel();
		String password = dataModel.generateHash(msg.m_request.getParameter("password"));	
		
		Resource newUserURI = null;
		inputModel = TDBFactory.createModel();
		newUserURI = inputModel.createResource(riv + username);

		Resource pending_group = inputModel.createResource(riv
				+ "rivela_pending");
		Resource group = inputModel.createResource(foaf + "Group");
		Resource agent = inputModel.createResource(foaf + "Agent");

		Property givenname = inputModel.createProperty(foaf, "givenname");
		Property family_name = inputModel.createProperty(foaf,
				"family_name");
		Property mbox = inputModel.createProperty(foaf, "mbox");
		Property member = inputModel.createProperty(foaf, "member");
		Property password_sha1sum = inputModel.createProperty(xfoaf,
				"password_sha1sum");
		Property nickname = inputModel.createProperty(foaf, "nickname");

		newUserURI.addProperty(nickname, username);
		newUserURI.addProperty(givenname, name);
		newUserURI.addProperty(family_name, lastname);
		newUserURI.addProperty(mbox, mail);
		newUserURI.addProperty(password_sha1sum, password);

		newUserURI.addProperty(RDF.type, agent);

		pending_group.addProperty(member, newUserURI);
		pending_group.addProperty(RDF.type, group);
		dataModel.writeOutPutModel(msg, inputModel);

		try {
			vcContext = createContext(msg);
			msg.m_ve.mergeTemplate(m_template, vcContext,
					msg.m_response.getWriter());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
